#pragma once 
#include<vector>
#include<string>
#include <sys/epoll.h>

#include <cstring>
#include <memory>

#include "base/Network.h"
#include "Event.h"
#include "PipeEvent.h"
#include "TimingWheel.h"
#include <unordered_map>

#include<functional>
#include<mutex>
#include<queue>

//是 Linux 系统中用于实现高性能 
//I/O 多路复用的头文件，提供了 epoll 相关的 AP
//事件循环都是在一个线程中的，所有不用加锁，这样可以提高性能

//同一进程内​​，​普通文件与 Socket 的 FD 不会重复
//但是也可以使用dup函数复制，​​复制 FD 时数值不同但指向同一资源
namespace tmms
{

    namespace network
    {
        using EventPtr = std::shared_ptr<Event>;
        using Func =std::function<void()>;
        class EventLoop:public TimingWheel
        { 
        public:
            EventLoop();
            ~EventLoop();

            void Loop();
            void Quit();
            void AddEvent(const EventPtr &event); //把描述符添加到这个map中，map的key是fd
            void DelEvent(const EventPtr &event);
            bool EnableEventReading(const EventPtr &event,bool enable);
            bool EnableEventWriting(const EventPtr &event,bool enable);

            void AssertInLoopThread();
            bool IsInLoopThread() const;
            
            void RunInLoop(const Func& f);
            void RunInLoop( Func&& f);
      
            void WakeUp();
        private:

            void RunFuctions();
            bool looping_{false};
            int epoll_fd_{-1};
            std::vector<struct epoll_event> epoll_events_;
            std::unordered_map<int,EventPtr> events_; //持有多个Event事件，一个Event事件就是一个fd_的读写，但是Event只是一个基类，需要子类重写他的wirte和read


            //这里都是测试用的拉，自定义的管道事件
            
            std::queue<Func> functions_;
            std::mutex lock_;
            PipeEventPtr pipe_event_;//自定义的管道事件，就是一个Event的子类  用来测试用的
        };
        
    }
}